{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 类  对象"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<__main__.Turtle object at 0x0000028C96AC4630>\n"
     ]
    }
   ],
   "source": [
    "class Turtle: # Python中的类名约定以大写字母开头\n",
    " #关于类的一个简单例子\n",
    " # 属性\n",
    "    color = 'green'\n",
    "    weight = 10\n",
    "    legs = 4\n",
    "    shell = True\n",
    "    mouth = '大嘴'\n",
    " # 方法\n",
    "    def climb(self):\n",
    "        print('我正在很努力的向前爬...')\n",
    "    def run(self):\n",
    "         print('我正在飞快的向前跑...')\n",
    "    def bite(self):\n",
    "         print('咬死你咬死你!!')\n",
    "    def eat(self):\n",
    "         print('有得吃，真满足...')\n",
    "    def sleep(self):\n",
    "         print('困了，睡了，晚安，zzz')\n",
    "#实例化\n",
    "tt = Turtle()\n",
    "print(tt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "我正在很努力的向前爬...\n"
     ]
    }
   ],
   "source": [
    "#调用方法\n",
    "tt.climb()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 5, 7, 8, 9]\n"
     ]
    }
   ],
   "source": [
    "# 继承：子类自动共享父类之间数据和方法的机制\n",
    "class MyList(list):\n",
    "    pass\n",
    "lst = MyList([1, 5, 2, 7, 8])\n",
    "lst.append(9)\n",
    "lst.sort()\n",
    "print(lst)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "pig is walking\n"
     ]
    }
   ],
   "source": [
    "#不同对象对同一方法响应不同的行动 不懂\n",
    "class Animal:\n",
    "    def run(self):\n",
    "        raise AttributeError('子类必须实现这个方法')\n",
    "class People(Animal):\n",
    "    def run(self):\n",
    "        print('人正在走')\n",
    "class Pig(Animal):\n",
    "    def run(self):\n",
    "        print('pig is walking')\n",
    "class Dog(Animal):\n",
    "    def run(self):\n",
    "        print('dog is running')\n",
    "#def func(animal):\n",
    "#    animal.run()\n",
    "#func(Pig()) #传入的是一整个对象\n",
    "anmial = Pig()\n",
    "anmial.run()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "我叫小傻狗,该死的，谁踢我...\n"
     ]
    }
   ],
   "source": [
    "#self,在调用方法时，无需明确提供与self对应的参数\n",
    "class Ball:\n",
    "    def setName(self, name):\n",
    "        self.name = name\n",
    "    def kick(self):\n",
    "        print(\"我叫%s,该死的，谁踢我...\" % self.name) #方法内调用属性？要用self.属性\n",
    "a = Ball()\n",
    "a.setName(\"小傻狗\")\n",
    "a.kick()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "我叫小傻狗,该死的，谁踢我...\n"
     ]
    }
   ],
   "source": [
    "#python的魔法方法 __init__方法  该方法在实例化的时候会被自动调用\n",
    "class Ball:\n",
    "    def __init__(self, name):\n",
    "        self.name = name\n",
    "    def kick(self):\n",
    "        print(\"我叫%s,该死的，谁踢我...\" % self.name) #方法内调用属性？要用self.属性\n",
    "a = Ball(\"小傻狗\")\n",
    "a.kick()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n",
      "2\n",
      "2\n"
     ]
    }
   ],
   "source": [
    "#公有和私有  在 Python 中定义私有变量只需要在变量名或函数名前加上“__”两个下划线，那么这个函数或变量就会为私有的了。\n",
    "\"\"\"类的私有属性实例\"\"\"\n",
    "#无法直接从实例化的对象象调用私有属性  私有属性只能在类的内部被调用\n",
    "class JustCounter:\n",
    "    __secretCount = 0 # 私有变量\n",
    "    publicCount = 0 # 公开变量\n",
    "    def count(self):\n",
    "        self.__secretCount += 1\n",
    "        self.publicCount += 1\n",
    "        print(self.__secretCount)\n",
    "counter = JustCounter()\n",
    "counter.count() # 1\n",
    "counter.count() # 2\n",
    "print(counter.publicCount) # 2\n",
    "print(counter._JustCounter__secretCount) # 2 Python的私有为伪私有\n",
    "#print(counter.__secretCount) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "#方法的私有化 私有方法只能在类的内部进行调用\n",
    "class Site:\n",
    "    def __init__(self, name, url):\n",
    "        self.name = name # public\n",
    "        self.__url = url # private\n",
    "    def who(self):\n",
    "        print('name : ', self.name)\n",
    "        print('url : ', self.__url)\n",
    "    def __foo(self): # 私有方法\n",
    "        print('这是私有方法')\n",
    "    def foo(self): # 公共方法\n",
    "        print('这是公共方法')\n",
    "        self.__foo()        #\n",
    "x = Site('老马的程序人生', 'https://blog.csdn.net/LSGO_MYP')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "name :  老马的程序人生\n",
      "url :  https://blog.csdn.net/LSGO_MYP\n"
     ]
    }
   ],
   "source": [
    "x.who()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "这是公共方法\n",
      "这是私有方法\n"
     ]
    }
   ],
   "source": [
    "x.foo()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "ename": "AttributeError",
     "evalue": "'Site' object has no attribute '__foo'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-4-6b29c9f2e0b8>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mx\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__foo\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mAttributeError\u001b[0m: 'Site' object has no attribute '__foo'"
     ]
    }
   ],
   "source": [
    "x.__foo()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "class people:\n",
    " # 定义基本属性\n",
    "    name = ''\n",
    "    age = 0\n",
    " # 定义私有属性,私有属性在类外部无法直接进行访问\n",
    "    __weight = 0\n",
    " # 定义构造方法\n",
    "    def __init__(self, n, a, w):\n",
    "        self.name = n\n",
    "        self.age = a\n",
    "        self.__weight = w #在类的内部调用私有属性\n",
    "    def speak(self):\n",
    "        print(\"%s 说: 我 %d 岁。\" % (self.name, self.age))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "class student(people):\n",
    "    grade = ''\n",
    "    def __init__(self, n, a, w, g):\n",
    " # 调用父类的方法\n",
    "        #people.__init__(self, n, a, w) #当子类没有定义属性时 会被父类中的属性覆盖\n",
    "        self.grade = g\n",
    " # 覆写父类的方法\n",
    "    def speak(self):\n",
    "        print(\"%s 说: 我 %d 岁了，我在读 %d 年级\" % (self.name, self.age, self.grade))\n",
    "s = student('小马的程序人生', 10, 60, 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " 说: 我 0 岁了，我在读 3 年级\n"
     ]
    }
   ],
   "source": [
    "s.speak()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 魔法方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "18"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class Rectangle:\n",
    "    def __init__(self, x, y):\n",
    "        self.x = x\n",
    "        self.y = y\n",
    "    def getPeri(self):\n",
    "        return (self.x + self.y) * 2\n",
    "    def getArea(self):\n",
    "        return self.x * self.y\n",
    "rect = Rectangle(4, 5)\n",
    "rect.getPeri() # 18"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "new方法是在一个对象被实例化的时候所调用的第一个方法，在调用init初始化之前，先调用new方法\n",
    "new至少要有一个参数，代表实例化的类\n",
    "new 对当前类进行了实例化，并将实例返回，传给 __init__ 的 self 。但是，执行了 __new__ ，并不一定会进入 __init__ ，只有 __new__ 返回了，当前类 cls 的实例，当前类的 __init__ 才会进入。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 迭代器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "字符串 列表 元组对象都可用于创建迭代器\n",
    "迭代器是一个可以记住元素的位置的对象"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "l\n",
      "s\n",
      "g\n",
      "o\n",
      "g\n",
      "r\n",
      "o\n",
      "u\n",
      "p\n"
     ]
    }
   ],
   "source": [
    "string = 'lsgogroup'\n",
    "for c in iter(string):\n",
    "    print(c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "B -> 百度\n",
      "A -> 阿里\n",
      "T -> 腾讯\n"
     ]
    }
   ],
   "source": [
    "links = {'B': '百度', 'A': '阿里', 'T': '腾讯'}\n",
    "for each in links:\n",
    "    print('%s -> %s' % (each, links[each]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "B -> 百度\n",
      "A -> 阿里\n",
      "T -> 腾讯\n"
     ]
    }
   ],
   "source": [
    "for each in iter(links):\n",
    "    print('%s -> %s' % (each, links[each]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "B\n",
      "A\n",
      "T\n"
     ]
    }
   ],
   "source": [
    "#迭代器主要包括iter 和 next 两个函数\n",
    "links = {'B': '百度', 'A': '阿里', 'T': '腾讯'}\n",
    "it = iter(links)\n",
    "print(next(it)) \n",
    "print(next(it)) \n",
    "print(next(it)) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 生成器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "调用一个生成器函数，返回的是一个迭代器对象。\n",
    "在调用生成器运行的过程中，每次遇到 yield 时函数会暂停并保存当前所有的运行信息，返回 yield 的值,并在下一次执行 next() 方法时从当前位置继续运行。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def myGen():\n",
    " print('生成器执行！')\n",
    " yield 1\n",
    " yield 2\n",
    "myG = myGen()\n",
    "print(next(myG)) \n",
    "# 生成器执行！\n",
    "# 1\n",
    "print(next(myG)) # 2\n",
    "print(next(myG)) # StopIteration\n",
    "myG = myGen()\n",
    "for each in myG:\n",
    " print(each)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "def myGen():\n",
    "    print('生成器执行！')\n",
    "    yield 1 #碰到yield函数时会暂停并保存当前所有的运行信息，返回yield的值。下一次执行时会从当前位置继续执行\n",
    "    yield 2  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "生成器执行！\n",
      "1\n"
     ]
    }
   ],
   "source": [
    "myG = myGen()\n",
    "print(next(myG)) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n"
     ]
    }
   ],
   "source": [
    "print(next(myG))#下一次执行会在当前位置继续执行"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "生成器执行！\n",
      "1\n",
      "153\n",
      "2\n",
      "153\n"
     ]
    }
   ],
   "source": [
    "myG = myGen()\n",
    "for each in myG: #可以用for循环代替each函数\n",
    "    print(each)\n",
    "    print(\"153\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "类这部分比较难，中间的讲解跳过很大一部分，等过两天时间空闲后慢慢看"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
